package com.wfm.mianshi;

import java.util.LinkedHashMap;
import java.util.Map;

public class LRUCacheWithTTL<K, V> {
    private final int capacity; // 缓存的最大容量
    private final long defaultTTL; // 默认的过期时间（毫秒）
    private final Map<K, CacheEntry<V>> cache; // 缓存存储

    public LRUCacheWithTTL(int capacity, long defaultTTL) {
        this.capacity = capacity;
        this.defaultTTL = defaultTTL;
        this.cache = new LinkedHashMap<K, CacheEntry<V>>(capacity, 0.75f, true) {
            @Override
            protected boolean removeEldestEntry(Map.Entry<K, CacheEntry<V>> eldest) {
                return size() > capacity; // 当缓存大小超过容量时，移除最久未使用的元素
            }
        };
    }

    // 添加缓存项，默认使用默认 TTL
    public void put(K key, V value) {
        put(key, value, defaultTTL);
    }

    // 添加缓存项，并指定 TTL
    public void put(K key, V value, long ttl) {
        long expirationTime = System.currentTimeMillis() + ttl; // 计算过期时间
        cache.put(key, new CacheEntry<>(value, expirationTime));
    }

    // 获取缓存项
    public V get(K key) {
        CacheEntry<V> entry = cache.get(key);
        if (entry == null) {
            return null; // 缓存中不存在该键
        }
        if (System.currentTimeMillis() > entry.expirationTime) {
            cache.remove(key); // 如果已过期，移除该缓存项
            return null;
        }
        return entry.value; // 返回缓存值
    }

    // 删除缓存项
    public void remove(K key) {
        cache.remove(key);
    }

    // 清空缓存
    public void clear() {
        cache.clear();
    }

    // 缓存项内部类
    private static class CacheEntry<V> {
        V value;
        long expirationTime;

        CacheEntry(V value, long expirationTime) {
            this.value = value;
            this.expirationTime = expirationTime;
        }
    }

    // 打印缓存内容（仅用于调试）
    public void printCache() {
        for (Map.Entry<K, CacheEntry<V>> entry : cache.entrySet()) {
            K key = entry.getKey();
            CacheEntry<V> cacheEntry = entry.getValue();
            System.out.println("Key: " + key + ", Value: " + cacheEntry.value +
                    ", Expiration Time: " + cacheEntry.expirationTime);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        LRUCacheWithTTL<String, String> cache = new LRUCacheWithTTL<>(3, 5000); // 容量为 3，TTL 为 5 秒

        cache.put("key1", "value1");
        cache.put("key2", "value2");
        cache.put("key3", "value3");

        System.out.println("Initial Cache:");
        cache.printCache();

        Thread.sleep(3000); // 等待 3 秒

        System.out.println("\nAfter 3 seconds:");
        System.out.println("Get key1: " + cache.get("key1")); // 应该返回 value1
        System.out.println("Get key2: " + cache.get("key2")); // 应该返回 value2

        Thread.sleep(3000); // 再等待 3 秒，总共 6 秒

        System.out.println("\nAfter 6 seconds:");
        System.out.println("Get key1: " + cache.get("key1")); // 应该返回 null（已过期）
        System.out.println("Get key2: " + cache.get("key2")); // 应该返回 null（已过期）

        cache.put("key4", "value4"); // 添加新缓存项
        System.out.println("\nAfter adding key4:");
        cache.printCache();
    }
}